package com.nsl.my_youlai.bbu_return.service;

import com.alibaba.excel.EasyExcel;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.nsl.my_youlai.bbu2.enums.BoardTypeEnum;
import com.nsl.my_youlai.bbu_return.enums.*;
import com.nsl.my_youlai.bbu_return.enums.check.VendorBbuModelEnum;
import com.nsl.my_youlai.bbu_return.model.bo.BBUFrame;
import com.nsl.my_youlai.bbu_return.model.bo.BBUSlot;
import com.nsl.my_youlai.bbu_return.model.bo.BbuBoard;
import com.nsl.my_youlai.bbu_return.model.bo.check.BbuCheckResult;
import com.nsl.my_youlai.bbu_return.model.vo.BbuCheckResultStringWrite;
import com.nsl.my_youlai.mystar.NslUtilJson;
import com.nsl.my_youlai.mystar.NslUtilPrinter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.SerializationUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

//todo:
// 非机框+风扇，必须有槽道号
// 厂家，网络类型和bbu型号匹配

@Slf4j
@Service
public class BBUCheckWithBoServiceImpl {

    //根据
    public Map<Integer,BbuCheckResult> bulidBbuCheckResultMap(List<BBUFrame> bbuFrameList){
        Map<Integer,BbuCheckResult> bbuCheckResultMap=new HashMap<>();
        for (BBUFrame bbuFrame : bbuFrameList) {
            bbuCheckResultMap.put(bbuFrame.getNodeBId(),new BbuCheckResult());
        }
        return  bbuCheckResultMap;
    }

    //第一步校验: 将所有bbu frame 对应的 BbuCheckResult ，放入list集合
    public List<BbuCheckResult> checkMinimumConfiguration(List<BBUFrame> bbuFrames,Map<Integer,BbuCheckResult> checkResultMap){
        for (BBUFrame bbuFrame : bbuFrames) {
            Map<Integer,BBUSlot> bbuSlotMap=bbuFrame.getBbuSlotMap();
            BbuCheckResult bbuCheckResult=checkResultMap.get(bbuFrame.getNodeBId());
            for (Integer slotInteger : bbuSlotMap.keySet()) {
                BBUSlot bbuSlot=bbuSlotMap.get(slotInteger);
                List<BbuBoard> bbuBoardList=bbuSlot.getBbuBoardList();
                bbuCheckResult.setNodeBId(bbuFrame.getNodeBId());
                for (BbuBoard bbuBoard : bbuBoardList) {
                    if(bbuBoard==null){
                        continue;
                    }
                    BoardTypeEnum boardType=bbuBoard.getBoardType();

                    switch (boardType){
                        case CONTROL_BOARD:
                            bbuCheckResult.setControlBoardCounter(bbuCheckResult.getControlBoardCounter()+1);
                            break;
                        case SWITCH_BOARD:
                            bbuCheckResult.setSwitchBoardCounter(bbuCheckResult.getSwitchBoardCounter()+1);
                            break;
                        case BASE_BAND_BOARD:
                            bbuCheckResult.setBaseBandBoardCounter(bbuCheckResult.getBaseBandBoardCounter()+1);
                            break;
                        case POWER_BOARD:
                            bbuCheckResult.setPowerBoardCounter(bbuCheckResult.getPowerBoardCounter()+1);
                            break;
                        case FUN:
                            bbuCheckResult.setFrameAndFunCounter(bbuCheckResult.getFrameAndFunCounter()+1);
                            break;
                        default:
                            throw new RuntimeException("nodeBid = "+bbuFrame.getNodeBId() +" 板卡类型错误。");
                    }

                }
            }

            //checkResultMap.put(bbuFrame.getNodeBId(),bbuCheckResult);
        }
        List<BbuCheckResult> bbuCheckResultList=checkResultMap.entrySet().stream().map(Map.Entry::getValue).collect(Collectors.toList());
        //最小配置检查
        for (BbuCheckResult bbuCheckResult : bbuCheckResultList) {
            List<String> minimumConfigurationList=bbuCheckResult.getMinimumConfigurationList();
            if(bbuCheckResult.getControlBoardCounter()==0 && bbuCheckResult.getSwitchBoardCounter()==0){
                minimumConfigurationList.add("无主控或交换板;");
            }
            if(bbuCheckResult.getBaseBandBoardCounter()==0){
                minimumConfigurationList.add("无基带板;");
            }
            if(bbuCheckResult.getPowerBoardCounter()==0){
                minimumConfigurationList.add("无电源板;");
            }
            if(bbuCheckResult.getFrameAndFunCounter()==0){
                minimumConfigurationList.add("无机框和风扇;");
            }
        }
        return bbuCheckResultList;
    }

    public void checkBoardMatchSlotListAndSlotRepeatedUse(List<BBUFrame> bbuFrames,Map<Integer,BbuCheckResult> bbuCheckResultMap)  {
        for (int i=0 ;i<bbuFrames.size();i++) {
            BBUFrame bbuFrame=bbuFrames.get(i);
            BbuCheckResult bbuCheckResult = bbuCheckResultMap.get(bbuFrame.getNodeBId());
            Map<Integer, BBUSlot> bbuSlotMap = bbuFrame.getBbuSlotMap();

            //String vendor=bbuFrame.getVendor();
//            VendorEnum vendorEnum=bbuFrame.getVendor();
//            GenerationTypeEnum generationTypeEnum=bbuFrame.getGenerationType();
            VendorBbuModelEnum bbuModelEnum=bbuFrame.getVendorBbuModelEnum();

            //log.info("bbuFrame = {}",bbuFrame);
            Map<BoardTypeEnum,List<Integer>> boardTypeEnumIntegerMap=bbuModelEnum.getBoardTypeSlotIndexMap();

            for (Map.Entry<Integer, BBUSlot> integerBBUSlotEntry : bbuSlotMap.entrySet()) {
                BBUSlot bbuSlot = integerBBUSlotEntry.getValue();
                List<BbuBoard> bbuBoardList = bbuSlot.getBbuBoardList();
                int boardCount = 0;
                for (BbuBoard bbuBoard : bbuBoardList) {
                    if (bbuBoard != null) {
                        boardCount++;
                    }
                }

                //大唐，4槽道，可以放置2块电源板
                if (boardCount > 2) {
                    bbuCheckResult.getSlotRepeatedUseList().add("槽道:" + bbuSlot.getSlotIndex() + "重复占用");
                } else if (boardCount == 2 && bbuFrame.getVendor() == VendorEnum.DT && bbuSlot.getSlotIndex() == 4){

                }else if(boardCount>1){
                    bbuCheckResult.getSlotRepeatedUseList().add("槽道:" + bbuSlot.getSlotIndex() + "重复占用");
                }

//                if(boardCount>1 && bbuFrame.getVendor()!=VendorEnum.DT && bbuSlot.getSlotIndex()!=4){
//                    bbuCheckResult.getSlotRepeatedUseList().add("槽道:"+bbuSlot.getSlotIndex()+"重复占用");
//                }
//
//                if(boardCount>2 && bbuFrame.getVendor()==VendorEnum.DT && bbuSlot.getSlotIndex()==4){
//                    bbuCheckResult.getSlotRepeatedUseList().add("槽道:"+bbuSlot.getSlotIndex()+"重复占用");
//                }

                for (BbuBoard bbuBoard : bbuBoardList) {
                    if(bbuBoard==null) continue;
                    BoardTypeEnum boardTypeEnum=bbuBoard.getBoardType();
                    if(boardTypeEnum.equals(BoardTypeEnum.FUN)){
                        continue;
                    }
                    if(bbuFrame.getNodeBId().intValue()==894347){

                        log.info("894347 result={}",NslUtilJson.convert2JsonPrettyAndNull(bbuCheckResultMap.get(894347)));
                    }
                    //log.info("boardTypeEnum = {}",boardTypeEnum);
                    List<Integer> slotIntegerRange=boardTypeEnumIntegerMap.get(boardTypeEnum);
                    if(!slotIntegerRange.contains(bbuSlot.getSlotIndex())){
                        bbuCheckResult.getBoardMatchSlotList().add("槽道:"+bbuSlot.getSlotIndex()+" 不能放置 "+bbuBoard.getBoardType().getLabel());
                    }
                }
            }
        }
    }

    /**
     * 检查目的nodeb id是否存在
     * @param bbuFrameMap
     * @param bbuCheckResultMap
     */
    public void checkDestinationBbuFrameNExist(Map<Integer,BBUFrame> bbuFrameMap,Map<Integer,BbuCheckResult> bbuCheckResultMap){
        List<BBUFrame> bbuFrameList=bbuFrameMap.entrySet().stream().map(Map.Entry::getValue).toList();
        Set<Integer> nodeIdSet=bbuFrameMap.keySet();
        for (int i=0 ;i<bbuFrameList.size();i++) {
            BBUFrame bbuFrame = bbuFrameList.get(i);
            BbuCheckResult bbuCheckResult = bbuCheckResultMap.get(bbuFrame.getNodeBId());
            Map<Integer, BBUSlot> bbuSlotMap = bbuFrame.getBbuSlotMap();
            List<BBUSlot> bbuSlotList=bbuSlotMap.entrySet().stream().map(Map.Entry::getValue).toList();
            for (BBUSlot bbuSlot : bbuSlotList) {
                List<BbuBoard> bbuBoardList=bbuSlot.getBbuBoardList();
                for (BbuBoard bbuBoard : bbuBoardList) {
                    Integer destinationNodeId=bbuBoard.getDestinationNodeBId();
                    if(isActionReuse(bbuBoard.getActionEnum())){
//                        if(bbuFrame.getNodeBId().intValue()==819659){
//                            log.info("819659 frame =",bbuFrame);
//                        }
                        if(!nodeIdSet.contains(destinationNodeId)){
                            bbuCheckResult.getDestinationBbuFrameNotExistList().add("拟安装 "+bbuBoard.getDestinationNodeBId()+ "的 BBU 不存在.");
                        }
                    }
                }
            }
        }
    }

    //跨厂家检查，现状阶段检查
    public void checkCrossVendorList(Map<Integer,BBUFrame> bbuFrameMap,Map<Integer,BbuCheckResult> bbuCheckResultMap){
        List<BBUFrame> bbuFrameList=bbuFrameMap.entrySet().stream().map(Map.Entry::getValue).toList();
        Set<Integer> nodeIdSet=bbuFrameMap.keySet();
        for (int i=0 ;i<bbuFrameList.size();i++) {
            BBUFrame bbuFrame = bbuFrameList.get(i);
            BbuCheckResult bbuCheckResult = bbuCheckResultMap.get(bbuFrame.getNodeBId());
            Map<Integer, BBUSlot> bbuSlotMap = bbuFrame.getBbuSlotMap();
            List<BBUSlot> bbuSlotList=bbuSlotMap.entrySet().stream().map(Map.Entry::getValue).toList();
            for (BBUSlot bbuSlot : bbuSlotList) {
                List<BbuBoard> bbuBoardList=bbuSlot.getBbuBoardList();
                for (BbuBoard bbuBoard : bbuBoardList) {
                    Integer destinationNodeId=bbuBoard.getDestinationNodeBId();
                    VendorEnum sourceVendor=bbuBoard.getVendor();
                    if(isActionReuse(bbuBoard.getActionEnum())){
                        if(nodeIdSet.contains(destinationNodeId)){
                            BBUFrame targetBbuFrame=bbuFrameMap.get(destinationNodeId);
                            VendorEnum targetVendor=targetBbuFrame.getVendor();

                            if(sourceVendor!=targetVendor){
                                bbuCheckResult.getCrossVendorList().add(sourceVendor.getLabel()+" => "+targetVendor.getLabel());
                            }
                        }
                    }
                }
            }
        }
    }

    //跨Tac检查，现状阶段检查
    public void checkCrossTacList(Map<Integer,BBUFrame> bbuFrameMap,Map<Integer,BbuCheckResult> bbuCheckResultMap){
        List<BBUFrame> bbuFrameList=bbuFrameMap.entrySet().stream().map(Map.Entry::getValue).toList();
        Set<Integer> nodeIdSet=bbuFrameMap.keySet();
        for (int i=0 ;i<bbuFrameList.size();i++) {
            BBUFrame bbuFrame = bbuFrameList.get(i);
            BbuCheckResult bbuCheckResult = bbuCheckResultMap.get(bbuFrame.getNodeBId());
            Map<Integer, BBUSlot> bbuSlotMap = bbuFrame.getBbuSlotMap();
            List<BBUSlot> bbuSlotList=bbuSlotMap.entrySet().stream().map(Map.Entry::getValue).toList();
            for (BBUSlot bbuSlot : bbuSlotList) {
                List<BbuBoard> bbuBoardList=bbuSlot.getBbuBoardList();
                for (BbuBoard bbuBoard : bbuBoardList) {
                    Integer destinationNodeId=bbuBoard.getDestinationNodeBId();

                    if(isActionReuse(bbuBoard.getActionEnum())){
                        if(nodeIdSet.contains(destinationNodeId)){
                            BBUFrame targetBbuFrame=bbuFrameMap.get(destinationNodeId);
                            Integer targetTac=targetBbuFrame.getTac();
                            Integer boardTac=bbuBoard.getTac();
                            //log.info("frame ={}",NslUtilJson.convert2JsonPrettyAndNull(bbuFrame));
                            //log.info("targetBbuFrame ={}",NslUtilJson.convert2JsonPrettyAndNull(targetBbuFrame));
                            if(boardTac.intValue()!=targetTac.intValue()){
                                bbuCheckResult.getCrossTacList().add(boardTac.intValue()+" => "+targetTac.intValue());
                            }
                        }
                    }
                }
            }
        }
    }

    //现状无问题后，采取动作之后检查
    public void doActions(Map<Integer,BBUFrame> sourceBbuFrameMap, Map<Integer,BBUFrame> targetBbuFrameMap){
        Set<Map.Entry<Integer,BBUFrame>> bbuEntrySet=sourceBbuFrameMap.entrySet();


        for (Map.Entry<Integer, BBUFrame> integerBBUFrameEntry : sourceBbuFrameMap.entrySet()) {
            BBUFrame targetBbuFrame= SerializationUtils.clone(integerBBUFrameEntry.getValue());
            targetBbuFrameMap.put(integerBBUFrameEntry.getKey(),targetBbuFrame);
        }

        //拆除入库的板卡，置为null
        for (BBUFrame bbuFrame : targetBbuFrameMap.values()) {

            Collection<BBUSlot> bbuSlotList=bbuFrame.getBbuSlotMap().values();

            for (BBUSlot bbuSlot : bbuSlotList) {
                List<BbuBoard> bbuBoardList=bbuSlot.getBbuBoardList();
                for (int j = 0; j < bbuBoardList.size(); j++) {
                    BbuBoard bbuBoard=bbuBoardList.get(j);
                    if(bbuBoard.getActionEnum()==ActionEnum.DISMANTLE_STORAGE_BOARD_RECYCLE || bbuBoard.getActionEnum()==ActionEnum.DISMANTLE_STORAGE_PORTS_INTEGRATION ){
                        bbuBoardList.set(j,null);
                    }
                }
            }
        }

        List<BBUFrame> bbuFrameList=bbuEntrySet.stream().map(Map.Entry::getValue).toList();
        for (int i=0;i<bbuFrameList.size();i++) {
            BBUFrame bbuFrame=bbuFrameList.get(i);
            if(bbuFrame.getNodeBId()==894347){
                log.info("bbu frame = {}",NslUtilJson.convert2JsonPrettyAndNull(bbuFrame));
                try {
                    NslUtilPrinter.printWithJacksonPretty((bbuFrame));
                } catch (JsonProcessingException e) {
                    throw new RuntimeException(e);
                }
            }
            //log.info("bbuFrame.getNodeBId() =",bbuFrame.getNodeBId());
           Set<Map.Entry<Integer,BBUSlot>> entrySet=bbuFrame.getBbuSlotMap().entrySet();
           List<BBUSlot> bbuSlotList=entrySet.stream().map(Map.Entry::getValue).collect(Collectors.toList());
            for (BBUSlot bbuSlot : bbuSlotList) {
                List<BbuBoard> bbuBoardList=bbuSlot.getBbuBoardList();

                for (int j = 0; j < bbuBoardList.size(); j++) {
                    BbuBoard bbuBoard=bbuBoardList.get(j);
                    if(isActionReuse(bbuBoard.getActionEnum())){

                        Integer destinationSlotIndex=bbuBoard.getDestinationSlotIndex();
                        //log.info("destinationSlotIndex = {}",destinationSlotIndex);
                        BBUFrame destinationBbuFrame=targetBbuFrameMap.get(bbuBoard.getDestinationNodeBId());
                        BBUFrame sourceBbuFrame=targetBbuFrameMap.get(bbuFrame.getNodeBId());

                        //目标是否存在，不存在保留错误信息
                        if(destinationBbuFrame==null){
                            //System.out.println(("拟安装 " + bbuBoard.getDestinationNodeBId() + "的 BBU 不存在."));
                        }else{
                            //bbuBoardIterator.remove();
                            List<BbuBoard> sourceBbuBoardList=sourceBbuFrame.getBbuSlotMap().get(bbuSlot.getSlotIndex()).getBbuBoardList();
                            sourceBbuBoardList.set(j,null);
                            Map<Integer,BBUSlot> destinationBbuSlotMap=destinationBbuFrame.getBbuSlotMap();

                            BBUSlot destinationSlot=null;
                            if(destinationBbuSlotMap.containsKey(bbuBoard.getDestinationSlotIndex())){
                                destinationSlot=destinationBbuSlotMap.get(destinationSlotIndex);
                            }else{
                                destinationSlot=new BBUSlot();
                                destinationSlot.setSlotIndex(destinationSlotIndex);
                                destinationBbuSlotMap.put(destinationSlotIndex,destinationSlot);
                            }
                            bbuBoard.setWhetherReused(true);
                            destinationSlot.getBbuBoardList().add(bbuBoard);
                        }
                    }
                    if(isActionReuse(bbuBoard.getActionEnum())){
                        BBUFrame sourceBbuFrame=targetBbuFrameMap.get(bbuFrame.getNodeBId());
                        List<BbuBoard> sourceBbuBoardList=sourceBbuFrame.getBbuSlotMap().get(bbuSlot.getSlotIndex()).getBbuBoardList();
                        sourceBbuBoardList.set(j,null);
                    }
                }
            }
        }
    }


    // 根据 bbu frame 下的所有bbu board 是否都为storage
    // 采取动作后，bbu board有4种状态： 0.不变  1. storage, 2.reused 成功: ActionEnum=reused,whetherReused=true,  3.reused失败：ActionEnum=reused,whetherReused=false;
    // 需要检查的bbuFrame: bbu board包含有 状态 0, 2,3
    public Map<Integer,BBUFrame>  calNeedCheckBbuFrameMap(Map<Integer,BBUFrame> targetBbuFrameMap){
        List <BBUFrame> bbuFrameList=targetBbuFrameMap.entrySet().stream().map(Map.Entry::getValue).collect(Collectors.toList());
        Map<Integer,BBUFrame> needCheckBbuFrameMap=new HashMap<>();
        for (BBUFrame bbuFrame : bbuFrameList) {
            boolean needCheck=false;
            List<BBUSlot> bbuSlotList=bbuFrame.getBbuSlotMap().entrySet().stream().map(Map.Entry::getValue).collect(Collectors.toList());
            for (BBUSlot bbuSlot : bbuSlotList) {
                List<BbuBoard> bbuBoardList=bbuSlot.getBbuBoardList();
                for (BbuBoard bbuBoard : bbuBoardList) {
                    if (bbuBoard == null) {
                        continue;
                    }
                    if (bbuBoard.getActionEnum() == ActionEnum.UNCHANGED || isActionReuse(bbuBoard.getActionEnum())) {
                        needCheck = true;
                        break;
                    }
                }
                if(needCheck) break;
            }
            if(needCheck){
                needCheckBbuFrameMap.put(bbuFrame.getNodeBId(),bbuFrame);
            }
        }
        return needCheckBbuFrameMap;
    }

    public void writeBbuCheckResult(String outputFilePath,List<BbuCheckResult> bbuCheckResultList){
        List<BbuCheckResultStringWrite> writeList=new ArrayList<>();
        for (BbuCheckResult bbuCheckResult : bbuCheckResultList) {
            BbuCheckResultStringWrite write=new BbuCheckResultStringWrite();
            write.setNodeBId(bbuCheckResult.getNodeBId());

            String okMessage="ok";

//            if(bbuCheckResult.getNodeBId().intValue()==819659){
//                log.info("819659 bbuCheckResult = {}",NslUtilJson.convert2JsonPrettyAndNull(bbuCheckResult));
//            }

            if(bbuCheckResult.getDestinationBbuFrameNotExistList().size()==0){
                write.setDestinationBbuFrameNotExist(okMessage);
            }else{
                write.setDestinationBbuFrameNotExist(bbuCheckResult.getDestinationBbuFrameNotExistList().toString());
            }

            if(bbuCheckResult.getBoardMatchSlotList().size()==0){
                write.setBoardMatchSlot(okMessage);
            }else{
                write.setBoardMatchSlot(bbuCheckResult.getBoardMatchSlotList().toString());
            }

            if(bbuCheckResult.getSlotRepeatedUseList().size()==0){
                write.setSlotRepeatedUse(okMessage);
            }else{
                //过滤掉槽道-1
                List<String> list=new ArrayList<>();

                for (String s : bbuCheckResult.getSlotRepeatedUseList()) {
                    if(!s.equals("槽道:-1重复占用")){
                        list.add(s);
                    }
                }
                write.setSlotRepeatedUse(list.toString());
            }

            if(bbuCheckResult.getMinimumConfigurationList().size()==0){
                write.setMinimumConfiguration(okMessage);
            }else{
                write.setMinimumConfiguration(bbuCheckResult.getMinimumConfigurationList().toString());
            }

            if(bbuCheckResult.getFrameAndFunCounter()>=2){
                write.setFrameCounterGreaterThan1("机框+风扇数量:"+bbuCheckResult.getFrameAndFunCounter());
            }

            if(bbuCheckResult.getControlBoardCounter()>2){
                write.setControlBoardCounterGreaterThan1("主控板数量:"+bbuCheckResult.getControlBoardCounter());
            }

            if(bbuCheckResult.getBaseBandBoardCounter()>4){
                write.setBaseBoardCounterGreaterThan3("基带板数量:"+bbuCheckResult.getBaseBandBoardCounter());
            }

            if(bbuCheckResult.getPowerBoardCounter()>2){
                write.setPowerBoardCounterGreaterThan1("电源板数量:"+bbuCheckResult.getPowerBoardCounter());
            }

            if(bbuCheckResult.getCrossVendorList().size()>0){
                write.setCrossVendorCheck(bbuCheckResult.getCrossVendorList().toString());
            }else{
                write.setCrossVendorCheck(okMessage);
            }

            if(bbuCheckResult.getCrossTacList().size()>0){
                write.setCrossTacCheck(bbuCheckResult.getCrossTacList().toString());
            }else{
                write.setCrossTacCheck(okMessage);
            }

            writeList.add(write);
        }

        EasyExcel.write(outputFilePath, BbuCheckResultStringWrite.class).sheet("check").doWrite(writeList);
    }


    boolean isActionReuse(ActionEnum actionEnum){
        List<ActionEnum> actionEnumList=new ArrayList<>();
        actionEnumList.add(ActionEnum.DISMANTLE_INTEGRATION_OF_ANCHOR);
        actionEnumList.add(ActionEnum.DISMANTLE_INTEGRATION);
        actionEnumList.add(ActionEnum.DISMANTLE_SETUP);
        actionEnumList.add(ActionEnum.DISMANTLE_SETUP_OF_ANCHOR);

        if(actionEnumList.contains(actionEnum)){
            return true;
        }else{
            return false;
        }
    }
}
